package com.dty.common.utils;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @ClassName LogUtils
 * @Description 日志打印输出
 * @Author 杨钧生
 * @Date 2020/12/21 12:39
 */
public class LogUtils {

    private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
    private static final DateTimeFormatter DAY_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static Level logOutLevel = Level.INFO;

    /**
     * @Description 初始日志设置
     */
    public static enum Level {

        DEBUG("DEBUG", 1), INFO("INFO ", 2), WARN("WARN ", 3), ERROR("ERROR", 4);

        private String tag;
        private int levelValue;

        private Level(String tag, int levelValue) {
            this.tag = tag;
            this.levelValue = levelValue;
        }

        public String getTag() {
            return this.tag;
        }

        public int getLevelValue() {
            return this.levelValue;
        }
    }

    /**
     * @param tag      类名标识
     * @param message  日志信息
     * @param fileName 文件名称（带文件扩展名）
     * @Description 打印 DEBUG 日志
     */
    public static void debug(String tag, String message, String fileName) {
        printLog(Level.DEBUG, tag, message, false, fileName);
    }

    /**
     * @param tag      类名标识
     * @param message  日志信息
     * @param fileName 文件名称（带文件扩展名）
     * @Description 打印 INFO 日志
     */
    public static void info(String tag, String message, String fileName) {
        printLog(Level.INFO, tag, message, false, fileName);
    }

    /**
     * @param tag      类名标识
     * @param message  日志信息
     * @param fileName 文件名称（带文件扩展名）
     * @Description 打印 WARN 日志
     */
    public static void warn(String tag, String message, String fileName) {
        printLog(Level.WARN, tag, message, false, fileName);
    }

    /**
     * @param tag      类名标识
     * @param message  日志信息
     * @param fileName 文件名称（带文件扩展名）
     * @Description 打印 ERROR 日志
     */
    public static void error(String tag, String message, String fileName) {
        printLog(Level.ERROR, tag, message, true, fileName);
    }

    /**
     * @param level      日志等级
     * @param tag        位置标识
     * @param message    日志信息
     * @param isOutToErr 是否是错误
     * @param fileName   日志文件
     * @Description 打印日志
     */
    private static void printLog(Level level, String tag, String message, boolean isOutToErr, String fileName) {
        if (level.getLevelValue() >= logOutLevel.getLevelValue()) {

            String log = LocalDateTime.now().format(DATE_FORMAT) + "  [" + level.getTag() + "]  " + tag + ": "
                    + message;

            if (("".equals(ConsoleIn.getConsoleTag()) || fileName.equals(ConsoleIn.getConsoleTag())) && !"stop".equals(ConsoleIn.getConsoleTag())) {
                outLogToConsole(isOutToErr, log);
            }

            outLogToFile(log, fileName);

        }
    }

    /**
     * @param isOutToErr 是否是错误
     * @param log        日志信息
     * @Description 控制台打印
     */
    private static void outLogToConsole(boolean isOutToErr, String log) {
        if (isOutToErr) {
            System.err.println(log);
        } else {
            System.out.println(log);
        }
    }

    /**
     * @param log      日志内容
     * @param fileName 文件名（不带扩展名）
     * @Description 日志文件打印
     */
    private static void outLogToFile(String log, String fileName) {

        try {
            Path fpath = Paths.get(RootPathUtils.getRootPath() + "/" + LocalDate.now().format(DAY_FORMAT) + "/" + fileName + ".log");
            // 创建文件
            if (!Files.exists(fpath)) {
                if (!Files.exists(fpath.getParent())) {
                    fpath.getParent().toFile().mkdirs();
                }
                Files.createFile(fpath);
            }
            // 创建BufferedWriter
            BufferedWriter bfw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fpath.toFile(), true)));
            bfw.write(log + "\n");
            bfw.flush();
            bfw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
